home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 17 / CU Amiga Magazine's Super CD-ROM 17 (1997)(EMAP Images)(GB)[!][issue 1997-12].iso / CUCD / Programming / DiceSource / src / vmake / process.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-09-09  |  11.9 KB  |  337 lines

  1. /*
  2.  *    (c)Copyright 1992-1997 Obvious Implementations Corp.  Redistribution and
  3.  *    use is allowed under the terms of the DICE-LICENSE FILE,
  4.  *    DICE-LICENSE.TXT.
  5.  */
  6. #include "vmake.h"
  7. #include <dos/dostags.h>
  8.  
  9. Prototype int InitSession(void);
  10. Prototype void TermSession(void);
  11. Prototype void PostLog(char *msg);
  12. Prototype int IssueCommand(char *cmd);
  13. Prototype int setup_cli(void);
  14.  
  15. /******************************************************************************/
  16. static APTR    pr_ConsoleTask;  /* Console handler process for current window */
  17.  
  18. static BPTR    Outfh;           /* Filehandle for session output              */
  19. static BPTR    Sesfh;           /* Filehandle for session Input/Output        */
  20. static LONG    cli_Interactive; /* Boolean; True if prompts required          */
  21. static LONG    cli_Background;  /* Boolean; True if CLI created by RUN        */
  22.  
  23. static struct Process *SesProcess;
  24. /******************************************************************************/
  25.  
  26. /***********************************************************************************
  27.  * Procedure: InitSession
  28.  * Synopsis:  rc = InitSession()FreeVec(vec);
  29.  * Purpose:   This code returns a vector to storage
  30.  ***********************************************************************************/
  31. int InitSession()
  32. {
  33.    struct FileHandle *handle;
  34.    struct CommandLineInterface *cli;
  35.  
  36.    if (!Sesfh)
  37.    {
  38. char cbuf[256];
  39.       SesProcess = (struct Process *)FindTask(0);
  40.       cli = BADDR(SesProcess->pr_CLI);
  41.  
  42.       /* Save the current console and background status information */
  43.       pr_ConsoleTask = SesProcess->pr_ConsoleTask;
  44.  
  45.       cli_Interactive    = cli->cli_Interactive;
  46.       cli_Background     = cli->cli_Background;
  47.  
  48.       /* Open up our console to do the work */
  49.       if (!build_command(cbuf, 255, global.text[CONFIG_CONSOLE], 0))
  50.          /* JAT's usual inverted logic... */
  51.          Sesfh = Open(cbuf, MODE_OLDFILE);
  52.       else
  53.          /* error message (since we don't knowwhat build_command() produced */
  54.          strcpy(cbuf, global.text[CONFIG_CONSOLE]);
  55.       if (Sesfh == NULL) 
  56.       {
  57.          Sesfh = Open("Con:0/0/320/100/Vmake_Default/Auto", MODE_OLDFILE);
  58.          if (Sesfh == NULL)
  59.             /* nowhere to put an error message, give up */
  60.             return(1);
  61.          else
  62.          {
  63.             char buf[256];
  64.             
  65.             sprintf(buf, "Bad Console \"%s\" from file: %s\n", 
  66.                     cbuf, Sym_Lookup(SYM_CONFIG));
  67.             PostLog(buf);
  68.          }
  69.       }
  70.       handle = (struct FileHandle *)(Sesfh << 2);
  71.       SesProcess->pr_CIS = SesProcess->pr_COS = Sesfh;
  72.  
  73.       SesProcess->pr_ConsoleTask = (APTR)handle->fh_Type;
  74.  
  75.       if (DOSBase->dl_lib.lib_Version >= 36)
  76.          Outfh = Open("*", MODE_NEWFILE);
  77.  
  78.       cli->cli_Interactive    = DOSTRUE;
  79.       cli->cli_Background     = DOSFALSE;
  80.       atexit(TermSession);
  81.    }
  82.    return(0);
  83. }
  84.  
  85. /***********************************************************************************
  86.  * Procedure: TermSession
  87.  * Synopsis:  (void)TermSession();
  88.  * Purpose:   Terminate usage of the Session
  89.  ***********************************************************************************/
  90. void TermSession()
  91. {
  92.    struct CommandLineInterface *cli;
  93.    if (Sesfh)
  94.    {
  95.       cli = BADDR(SesProcess->pr_CLI);
  96.  
  97.       Close(Sesfh);
  98.       if (Outfh) Close(Outfh);
  99.       Sesfh = Outfh = 0;
  100.       SesProcess->pr_ConsoleTask = pr_ConsoleTask;
  101.       cli->cli_Interactive       = cli_Interactive;
  102.       cli->cli_Background        = cli_Background;
  103.    }
  104. }
  105.  
  106. /***********************************************************************************
  107.  * Procedure: PostLog
  108.  * Synopsis:  (void)PostLog(message);
  109.  * Purpose:   Output a message to the session log
  110.  ***********************************************************************************/
  111. void PostLog(char *msg)
  112. {
  113.    if (!InitSession())
  114.    {
  115.       Write(Sesfh, msg, strlen(msg));
  116.       Write(Sesfh, "\n", 1);
  117.    }
  118. }
  119.  
  120.  
  121. /***********************************************************************************
  122.  * Procedure: IssueCommand
  123.  * Synopsis:  rc = IssueCommand(cmd);
  124.  * Purpose:   Execute a given command with the current console
  125.  ***********************************************************************************/
  126. int IssueCommand(char *cmd)
  127. {
  128.    int rc;
  129.    struct TagItem taglist[4];
  130.  
  131.    rc = InitSession();
  132.    if (!rc)
  133.    {
  134.       if (Outfh)
  135.       {
  136.          taglist[0].ti_Tag  = SYS_UserShell;
  137.          taglist[0].ti_Data = 1;
  138.          taglist[1].ti_Tag  = SYS_Input;
  139.          taglist[1].ti_Data = (ULONG)Sesfh;
  140.          taglist[2].ti_Tag  = SYS_Output;
  141.          taglist[2].ti_Data = (ULONG)Outfh;
  142.          taglist[3].ti_Tag  = TAG_DONE;
  143.  
  144.          rc = SystemTagList(cmd, taglist);
  145.       }
  146.       else
  147.       {
  148.          rc = Execute(cmd, 0L, Sesfh);
  149.       }
  150.    }
  151.    return(rc);
  152. }
  153.  
  154. /***********************************************************************************
  155.  * Procedure: Alloc_Vec
  156.  * Synopsis:  newvec = Alloc_Vec(size);
  157.  * Purpose:   This code allocates a DOS vector
  158.  * Note:      This storage is NOT automatically freed by the compiler library.
  159.  ***********************************************************************************/
  160. static BPTR Alloc_Vec(int size)
  161. {
  162.    long *new;
  163.  
  164.    size += 4;
  165.    /* Based on the given size, allocate the right amount of memory */
  166.    new = (long *)AllocMem(size, MEMF_PUBLIC | MEMF_CLEAR);
  167.  
  168.    if (new != NULL)
  169.    {
  170.       /* Remember to point one past the length longword */
  171.       *new++ = size;
  172.    }
  173.    else
  174.    {
  175.       request(1, TEXT_NOMEM, NULL, NULL);
  176.    }
  177.    return(MKBADDR(new));
  178. }
  179.  
  180. /***********************************************************************************
  181.  * Procedure: Free_Vec
  182.  * Synopsis:  (void)FreeVec(vec);
  183.  * Purpose:   This code returns a vector to storage
  184.  ***********************************************************************************/
  185. static void Free_Vec(BPTR orig)
  186. {
  187.    long *in;
  188.  
  189.    in = (long *)BADDR(orig);
  190.    in--;  /* Back up to the size information for the original allocation */
  191.  
  192.    /* Based on the given size, allocate the right amount of memory */
  193.    FreeMem(in, *in);
  194. }
  195.  
  196. /* This structure maps a DOS Path entry.  This is not really documented in any */
  197. /* of the DOS include files but is generally understood                        */
  198. /* Note that it must allocated as a dos vector (length byte in front of it)    */
  199. struct PathEnt {
  200.   BPTR nextent;
  201.   BPTR lock;
  202. };
  203.  
  204. /***********************************************************************************
  205.  * Procedure: freecli
  206.  * Synopsis:  (void)freecli();
  207.  * Purpose:   This code frees up any CLI allocated structures.
  208.  * Note:      This routine is only called as an autoexit routine when setup_cli
  209.  *            has done some work.  Otherwise we assume that no special work had to
  210.  *            be done to make things happen.
  211.  ***********************************************************************************/
  212. static void freecli()
  213. {
  214.    struct CommandLineInterface *cli;
  215.    BPTR oldent;
  216.  
  217.    cli = BADDR(SesProcess->pr_CLI);
  218.  
  219.    if (!cli) return;
  220.  
  221.    /* We only need to free the 4 vectors we created and all of the */
  222.    /* locks on the the path list.                                  */
  223.    Free_Vec(cli->cli_SetName);
  224.    Free_Vec(cli->cli_CommandName);
  225.    Free_Vec(cli->cli_Prompt);
  226.    Free_Vec(cli->cli_CommandFile);
  227.  
  228.    while((oldent = cli->cli_CommandDir) != 0)
  229.    {
  230.       struct PathEnt *pathent;
  231.  
  232.       /* First we need to remove us from the path list */
  233.       pathent = BADDR(oldent);
  234.       cli->cli_CommandDir = pathent->nextent;
  235.       UnLock(pathent->lock);     /* Free the lock at this entry        */
  236.       Free_Vec(oldent);          /* Free the storage for the path node */
  237.    }
  238.    SesProcess->pr_CLI = 0;
  239. }
  240.  
  241. /***********************************************************************************
  242.  * Procedure: setup_cli()
  243.  * Synopsis:  (void)setup_cli();
  244.  * Purpose:   This code sets up a fake CLI structure by copying the appropriate
  245.  *            information from workbench.  It will prepare for that to be
  246.  *            automatically be freed on program termination through freecli.
  247.  ***********************************************************************************/
  248. int setup_cli()
  249. {
  250.    struct CommandLineInterface *cli, *wbcli;
  251.    struct Process *wbproc;
  252.    struct PathEnt *pathent, *wbent;
  253.  
  254.    SesProcess = (struct Process *)FindTask(0);
  255.  
  256.    /* Allocate a CLI structure if we need one                        */
  257.    if (SesProcess->pr_CLI) return;
  258.  
  259.    cli = get_mem(sizeof(struct CommandLineInterface));
  260.    if (cli == NULL) return(1);
  261.  
  262.    atexit(freecli);
  263.  
  264.    /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  265.    /* Next we need to go through and copy the workbench path over to      */
  266.    /* Our process.  The only things we need to duplicate are:             */
  267.    /*                                                                     */
  268.    /* We need to copy over the BPTR link list for this one.               */
  269.    /*    pr_CLI->cli_CommandDir   Head of the path locklist               */
  270.    /*                                                                     */
  271.    /* These are buffers which we need to allocate space for and clone     */
  272.    /*    pr_CLI->cli_SetName      Name of current directory               */
  273.    /*    pr_CLI->cli_CommandName  Name of current command                 */
  274.    /*    pr_CLI->cli_Prompt       Current prompt (set by PROMPT)          */
  275.    /*    pr_CLI->cli_CommandFile  Name of EXECUTE command file            */
  276.    /*                                                                     */
  277.    /* These fields are just copied over verbatim                          */
  278.    /*    pr_CLI->cli_FailLevel    Fail level (set by FAILAT)              */
  279.    /*    pr_CLI->cli_Interactive  Boolean; True if prompts required       */
  280.    /*    pr_CLI->cli_Background   Boolean; True if CLI created by RUN     */
  281.    /*    pr_CLI->cli_DefaultStack Stack size to be obtained in long words */
  282.    /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  283.    SesProcess->pr_CLI = MKBADDR(cli);
  284.  
  285.    /* Now we need to find the workbench CLI */
  286.    if ( ( (wbproc = (struct Process *)FindTask("Workbench")) == NULL) &&
  287.         ( (wbproc = (struct Process *)FindTask("Fastbench")) == NULL) )
  288.    {
  289.       /* For some reason workbench and FastBench are not in the system */
  290.       /* We need to punt and not let them really do any work           */
  291.       return(2);
  292.    }
  293.    wbcli = BADDR(wbproc->pr_CLI);
  294.  
  295.    /* Say what??  We have a workbench but it doesn't have a CLI???   */
  296.    if (wbcli == NULL) return(3);
  297.  
  298.    /* Do all of the staight copies from the Workbench CLI */
  299.    cli->cli_FailLevel    = 20;
  300.    cli->cli_Interactive  = DOSFALSE;
  301.    cli->cli_Background   = DOSFALSE;
  302.    cli->cli_DefaultStack = 2048; /* Longwords */
  303.  
  304.    /* Next we get all of the cloned vector buffers */
  305.    cli->cli_SetName      = Alloc_Vec( 80);  /* These numbers are truely magic  */
  306.    cli->cli_CommandName  = Alloc_Vec(104);  /* and CAN NOT be changed for true */
  307.    cli->cli_Prompt       = Alloc_Vec( 60);  /* compatibility with 1.3.         */
  308.    cli->cli_CommandFile  = Alloc_Vec( 40);  /* Don't even try to change them   */
  309.  
  310.    /* Lastly we need to copy over all of the paths from workbench */
  311.    if (wbcli->cli_CommandDir)
  312.    {
  313.       /* Start out the process by copying over the first vector */
  314.       cli->cli_CommandDir = Alloc_Vec(8);
  315.       wbent   = BADDR(wbcli->cli_CommandDir);
  316.       pathent = BADDR(cli->cli_CommandDir);
  317.  
  318.       /* Now loop through copying over the vector and then replacing everything */
  319.       /* in place.  This looks a little strange because we are actually counting */
  320.       /* on creating a structure with a pointer to the other linked list, but  */
  321.       while(wbent->nextent)
  322.       {
  323.          pathent->nextent = Alloc_Vec(8);
  324.          pathent->lock = DupLock(wbent->lock);
  325.          if (!pathent->lock)
  326.          {
  327.             pathent->nextent = 0;  /* Make sure we terminate the list here */
  328.             return(4);
  329.          }
  330.          wbent   = BADDR(wbent->nextent);
  331.          pathent = BADDR(pathent->nextent);
  332.       }
  333.       pathent->lock = DupLock(wbent->lock);
  334.       if (!pathent->lock) return(5);
  335.    }
  336. }
  337.